package ru.volgogradetzzz.math {
	/**
	 * ...
	 * @author nvc
	 */
	public class VMatrix3x3 {
		public var m11:Number, m12:Number, m13:Number;
		public var m21:Number, m22:Number, m23:Number;
		public var m31:Number, m32:Number, m33:Number;
		
		public function VMatrix3x3(	m11:Number = 1, m12:Number = 0, m13:Number = 0,
									m21:Number = 0, m22:Number = 1, m23:Number = 0,
									m31:Number = 0, m32:Number = 0, m33:Number = 1) {
			this.m11 = m11; this.m12 = m12; this.m13 = m13;
			this.m21 = m21; this.m22 = m22; this.m23 = m23;
			this.m31 = m31; this.m32 = m32; this.m33 = m33;
		}
		
		public function identity():void {
			m11 = 1; m12 = 0; m13 = 0;
			m21 = 0; m22 = 1; m23 = 0;
			m31 = 0; m32 = 0; m33 = 1;
		}
		
		public function multiplyByMatrix(m:VMatrix3x3):void {
			var temp11:Number = m11 * m.m11 + m12 * m.m21 + m13 * m.m31;
			var temp12:Number = m11 * m.m12 + m12 * m.m22 + m13 * m.m32;
			var temp13:Number = m11 * m.m13 + m12 * m.m23 + m13 * m.m33;
			var temp21:Number = m21 * m.m11 + m22 * m.m21 + m23 * m.m31;
			var temp22:Number = m21 * m.m12 + m22 * m.m22 + m23 * m.m32;
			var temp23:Number = m21 * m.m13 + m22 * m.m23 + m23 * m.m33;
			var temp31:Number = m31 * m.m11 + m32 * m.m21 + m33 * m.m31;
			var temp32:Number = m31 * m.m12 + m32 * m.m22 + m33 * m.m32;
			var temp33:Number = m31 * m.m13 + m32 * m.m23 + m33 * m.m33;
			
			m11 = temp11; m12 = temp12; m13 = temp13;
			m21 = temp21; m22 = temp22; m23 = temp23;
			m31 = temp31; m32 = temp32; m33 = temp33;
		}
		
		public function multiplyByMatrixReturn(m:VMatrix3x3):VMatrix3x3 {
			var newM:VMatrix3x3 = new VMatrix3x3();
			newM.m11 = m11 * m.m11 + m12 * m.m21 + m13 * m.m31;
			newM.m12 = m11 * m.m12 + m12 * m.m22 + m13 * m.m32;
			newM.m13 = m11 * m.m13 + m12 * m.m23 + m13 * m.m33;
			newM.m21 = m21 * m.m11 + m22 * m.m21 + m23 * m.m31;
			newM.m22 = m21 * m.m12 + m22 * m.m22 + m23 * m.m32;
			newM.m23 = m21 * m.m13 + m22 * m.m23 + m23 * m.m33;
			newM.m31 = m31 * m.m11 + m32 * m.m21 + m33 * m.m31;
			newM.m32 = m31 * m.m12 + m32 * m.m22 + m33 * m.m32;
			newM.m33 = m31 * m.m13 + m32 * m.m23 + m33 * m.m33;
			
			return newM;
		}
		
		public function setupRotation(angX:Number, angY:Number, angZ:Number):void {
			var sinX:Number = Math.sin(angX);
			var cosX:Number = Math.cos(angX);
			
			var sinY:Number = Math.sin(angY);
			var cosY:Number = Math.cos(angY);
			
			var sinZ:Number = Math.sin(angZ);
			var cosZ:Number = Math.cos(angZ);
			
			m11 = cosY * cosZ; 	m12 = -sinX * sinY * cosZ + cosX * sinZ;	m13 = cosX * sinY * cosZ + sinX * sinZ;
			m21 = -cosY * sinZ; m22 = sinX * sinY * sinZ + cosX * cosZ;		m23 = -cosX * sinY * sinZ + sinX * cosZ
			m31 = -sinY; 		m32 = -sinX * cosY;							m33 = cosX * cosY;
		}
		
		public function setupRotationX(angX:Number):void {
			var sin:Number = Math.sin(angX);
			var cos:Number = Math.cos(angX);
			
			m22 = cos;	m23 = -sin;
			m32 = sin; m33 = cos;
		}
		
		public function setupRotationY(angY:Number):void {
			var sin:Number = Math.sin(angY);
			var cos:Number = Math.cos(angY);
			
			m11 = cos; 	m13 = sin;
			m31 = -sin; m33 = cos;
		}
		
		public function setupRotationZ(angZ:Number):void {
			var sin:Number = Math.sin(angZ);
			var cos:Number = Math.cos(angZ);
			
			m11 = cos; 	m12 = -sin;
			m21 = sin; 	m22 = cos;
		}
		
		public function transpose():void {
			var temp12:Number = m12;
			var temp13:Number = m13;
			var temp23:Number = m23;
			
			m12 = m21;
			m13 = m31;
			
			m21 = temp12;
			m23 = m32;
			
			m31 = temp13;
			m32 = temp23;
		}
		
		public function clone():VMatrix3x3 {
			return new VMatrix3x3(	m11, m12, m13,
									m21, m22, m23,
									m31, m32, m33);
		}
		
		public function copyTo(m:VMatrix3x3):void {
			m.m11 = m11; m.m12 = m12; m.m13 = m13;
			m.m21 = m21; m.m22 = m22; m.m23 = m23;
			m.m31 = m31; m.m32 = m32; m.m33 = m33;
		}
		
		public function copyFrom(m:VMatrix3x3):void {
			m11 = m.m11; m12 = m.m12; m13 = m.m13;
			m21 = m.m21; m22 = m.m22; m23 = m.m23;
			m31 = m.m31; m32 = m.m32; m33 = m.m33;
		}
		
		public function toString():String {
			return 	'[' + m11 + ', ' + m12 + ', ' + m13 + ',\n' +
					' ' + m21 + ', ' + m22 + ', ' + m23 + ',\n' +
					' ' + m31 + ', ' + m32 + ', ' + m33 + ']';
		}
	}
}